package com.ansion.baseui.base;

import android.app.Activity;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import androidx.annotation.CallSuper;
import androidx.annotation.IdRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;

import com.ansion.basetool.observer.ListenerManager;
import com.ansion.basetool.preconditions.Preconditions;
import com.ansion.baseui.R;
import com.ansion.baseui.base.actionbar.TActionBar;
import com.ansion.BridgeCallback;
import com.ansion.baseui.base.click.AvoidDoubleClickListener;
import com.ansion.utils.dark.setting.DarkSetting;
import com.ansion.baseui.base.loading.CustomAlertDialog;
import com.ansion.baseui.base.toolbar.TActionBarSupport;
import com.ansion.utils.IntentUtils;
import com.ansion.utils.StatusBarUtils;
import com.ansion.utils.ThemeActivity;

/**
 * @author zhaoyuntao
 * date 2021/6/27
 */
public abstract class TBaseActivity extends ThemeActivity implements View.OnClickListener, ToastSupport, TActionBarSupport, LoadingSupport {

    private TActionBar actionBar;
    private CustomAlertDialog loadingDialog;
    private final ListenerManager<TOnBackPressListener> onBackPressListeners = new ListenerManager<>(true);

    @Override
    final protected void onCreate(@Nullable Bundle savedInstanceState) {
        if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O) {
            CompatForAndroid8.tryToFixOrientation(this);
        }
        beforeSuperCreate(savedInstanceState);
        super.onCreate(savedInstanceState);
        onCreateActivity(savedInstanceState);
    }

    protected void beforeSuperCreate(Bundle savedInstanceState) {
    }

    protected boolean beforeInitView() {
        return true;
    }

    final protected void onCreateActivity(@Nullable Bundle savedInstanceState) {
        FrameLayout rootView = new FrameLayout(activity());
        rootView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        boolean useDefaultActionBar = onSetTActionBarVisible();
        //Content view.
        FrameLayout containerView = new FrameLayout(rootView.getContext());
        FrameLayout.LayoutParams layoutParamsOfContainer = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        layoutParamsOfContainer.gravity = Gravity.TOP;
        layoutParamsOfContainer.topMargin = !useDefaultActionBar || onSetTActionBarImmersion() ? 0 : onInitTActionBarHeight();
        containerView.setLayoutParams(layoutParamsOfContainer);
        rootView.addView(containerView);
        //Action bar.
        if (useDefaultActionBar) {
            actionBar = onCreateTActionBar();
            rootView.addView(actionBar);
        }

        setContentView(rootView);

        View contentView = createContentView(savedInstanceState);
        if (contentView != null) {
            containerView.addView(contentView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
        } else {
            int contentViewRes = initContentView(savedInstanceState);
            if (contentViewRes > 0) {
                LayoutInflater.from(activity()).inflate(contentViewRes, containerView, true);
            }
        }
        if (!beforeInitView()) {
            return;
        }
        initView_base(savedInstanceState);
        initData_base(savedInstanceState);
    }

    public void setStatusBarWhite() {
//        Window window = getWindow();
//        window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//        window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
//        window.setStatusBarColor(ContextCompat.getColor(this, R.color.gray_1));
        StatusBarUtils.setRootViewFitsSystemWindows(this, true);
        StatusBarUtils.setStatusBarColor(this, ContextCompat.getColor(this, R.color.gray_1));
        StatusBarUtils.setStatusBarDarkTheme(this, !DarkSetting.isCurrentDarkMode());
    }

    @NonNull
    @Override
    final public TActionBar getTActionBar() {
        Preconditions.checkNotNull(actionBar, "Try to get TActionBar with onSetTActionBarVisible return true");
        return actionBar;
    }

    @NonNull
    final public TActionBar getActionbar() {
        Preconditions.checkNotNull(actionBar, "Try to get TActionBar with onSetTActionBarVisible return true");
        return actionBar;
    }

    @NonNull
    public TActionBar onCreateTActionBar() {
        TActionBar actionBar = new TActionBar(activity());
        FrameLayout.LayoutParams layoutParamsOfActionBar = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, onInitTActionBarHeight());
        layoutParamsOfActionBar.gravity = Gravity.TOP;
        actionBar.setLayoutParams(layoutParamsOfActionBar);
        actionBar.setArrowViewClickListener(this::onClickTActionBarArrow);
        actionBar.setTitleViewClickListener(this::onClickTActionBarTitle);
        int layoutRes = initCustomTActionBar();
        if (layoutRes != -1) {
            actionBar.setCustomTitleView(layoutRes);
        }
        return actionBar;
    }

    protected void onClickTActionBarArrow(View view) {
        finish();
    }

    protected void onClickTActionBarTitle(View view) {

    }

    @Nullable
    protected View createContentView(@Nullable Bundle savedInstanceState) {
        return null;
    }

    @LayoutRes
    protected abstract int initContentView(@Nullable Bundle savedInstanceState);

    @LayoutRes
    protected int initCustomTActionBar() {
        return -1;
    }

    protected abstract void initView_base(Bundle savedInstanceState);

    protected abstract void initData_base(Bundle savedInstanceState);

    @Override
    final public Activity activity() {
        return this;
    }

    @Override
    final public CustomAlertDialog getLoadingDialog() {
        return loadingDialog;
    }

    @Override
    final public void onSetLoadingDialog(@Nullable CustomAlertDialog loadingDialog) {
        this.loadingDialog = loadingDialog;
    }

    protected void goToActivity(Class<?> t) {
        Intent intent = new Intent(this, t);
        startActivity(intent);
    }

    public void goToActivity(Class<?> t, @Nullable Bundle bundle) {
        Intent intent = new Intent(this, t);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivity(intent);
    }

    public void goToActivity(Class<? extends Activity> t, String key, String value) {
        Intent intent = new Intent(this, t);
        if (!TextUtils.isEmpty(key)) {
            intent.putExtra(key, value);
        }
        startActivity(intent);
    }

    protected <T extends View> T registerOnClickListener(@NonNull T view) {
        view.setOnClickListener(new AvoidDoubleClickListener() {
            @Override
            public void onClickView(View view) {
                TBaseActivity.this.onClick(view);
            }
        });
        return view;
    }

    protected <T extends View> T registerOnClickListener(@IdRes int resId) {
        T view = findViewById(resId);
        return registerOnClickListener(view);
    }

    protected <T extends View> T registerOnClickListener(View rootView, @IdRes int resId) {
        T view = rootView.findViewById(resId);
        return registerOnClickListener(view);
    }

    @Override
    public void onClick(View v) {
    }

    final protected Bundle getBundle() {
        Intent intent = getIntent();
        if (intent == null) {
            return null;
        }
        return intent.getExtras();
    }

    final protected Bundle getBundleIfNullFinish() {
        Intent intent = getIntent();
        if (intent == null) {
            finish();
            return null;
        }
        Bundle bundle = intent.getExtras();
        if (bundle == null) {
            finish();
        }
        return bundle;
    }

    final protected String getStringFromBundle(String key) {
        return getStringFromBundle(key, false);
    }

    final protected String getStringFromBundle(String key, boolean remove) {
        Bundle bundle = getBundle();
        if (bundle == null) {
            return null;
        }
        String value = bundle.getString(key);
        if (remove) {
            bundle.remove(key);
        }
        return value;
    }

    final protected int getIntFromBundle(String key, int defaultValue) {
        Bundle bundle = getBundle();
        if (bundle == null) {
            return defaultValue;
        }
        return bundle.getInt(key);
    }

    final protected long getLongFromBundle(String key, long defaultValue) {
        Bundle bundle = getBundle();
        if (bundle == null) {
            return defaultValue;
        }
        return bundle.getLong(key);
    }

    final protected String getStringFromIntentIfNullFinish(String key) {
        Intent intent = getIntent();
        if (intent == null || !intent.hasExtra(key) || TextUtils.isEmpty(intent.getStringExtra(key))) {
            finish();
            return null;
        }
        return intent.getStringExtra(key);
    }

    final protected double getDoubleFromIntent(String key, double defaultValue) {
        Intent intent = getIntent();
        if (intent == null || !intent.hasExtra(key)) {
            return defaultValue;
        }
        return intent.getDoubleExtra(key, defaultValue);
    }

    final protected String getStringFromIntentIfNullThrowException(String key) {
        Intent intent = getIntent();
        Preconditions.checkNotNull(intent);
        Preconditions.checkNotEmpty(intent.getStringExtra(key));
        return intent.getStringExtra(key);
    }

    final protected boolean getBooleanFromBundle(String key) {
        Bundle bundle = getBundle();
        if (bundle == null) {
            return false;
        }
        return bundle.getBoolean(key);
    }

    final protected boolean getBooleanFromBundleIfNullFinish(String key) {
        Bundle bundle = getBundle();
        if (bundle == null) {
            finish();
            return false;
        }
        return bundle.getBoolean(key);
    }

    final protected boolean getBooleanFromBundle(String key, boolean defaultValue) {
        return getBooleanFromBundle(key, defaultValue, false);
    }

    final protected boolean getBooleanFromBundle(String key, boolean defaultValue, boolean remove) {
        Bundle bundle = getBundle();
        if (bundle == null) {
            return defaultValue;
        }
        boolean value = bundle.getBoolean(key, defaultValue);
        if (remove) {
            bundle.remove(key);
        }
        return value;
    }

    public void addOnBackPressListener(TOnBackPressListener tOnBackPressListener) {
        onBackPressListeners.addListener(tOnBackPressListener);
    }

    /**
     * Please don't override this method.
     * Use {@link #onKeyPressedDownBase(int keyCode, KeyEvent event)} instead.
     *
     * @return true means consume this click
     */
    @Override
    final public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (onKeyPressedDownBase(keyCode, event)) {
            return true;
        } else {
            return super.onKeyDown(keyCode, event);
        }
    }

    protected boolean onKeyPressedDownBase(int keyCode, KeyEvent event) {
        return false;
    }

    /**
     * Please don't override this method.
     * Use {@link #onPressBack()} instead.
     */
    @Override
    final public void onBackPressed() {
        if (onBackPressListeners.notifyListeners(TOnBackPressListener::onBackPressed)) {
            return;
        }
        if (onPressBack()) {
            return;
        }
        super.onBackPressed();
    }

    /**
     * When press back key.
     *
     * @return true means consume this click
     */
    protected boolean onPressBack() {
        return false;
    }

    //can Override
    protected boolean onFinish() {
        return true;
    }

    /**
     * This method will be called after super.finish() is called.
     */
    protected void onPostFinish() {
        // nothing to do
    }

    //Don't override this method.
    @Override
    final public void finish() {
        if (onFinish()) {
            super.finish();
            onPostFinish();
        }
    }

    protected int onOverrideEnterAnimate() {
        return -1;
    }

    @Deprecated
    @Override
    public void startActivityForResult(Intent intent, int requestCode) {
        super.startActivityForResult(intent, requestCode);
    }

    @Deprecated
    @Override
    public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
        super.startActivityForResult(intent, requestCode, options);
    }

    @Deprecated
    @CallSuper
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    }

    final public void startActivityForResult(Intent intent, BridgeCallback callback) {
        IntentUtils.startActivityForResult(activity(), intent, callback);
    }

    final public void startActivityForResult(@NonNull Class<?> cls, BridgeCallback callback) {
        IntentUtils.startActivityForResult(this, cls, null, callback);
    }

    final public void startActivityForResult(@NonNull Class<?> cls, @Nullable Bundle args, BridgeCallback callback) {
        IntentUtils.startActivityForResult(this, cls, args, callback);
    }

    @Override
    final protected void onResume() {
        super.onResume();
        _onResumeActivity();
        onResumeActivity();
    }

    protected void _onResumeActivity() {
    }

    protected void onResumeActivity() {
    }

    final protected void onPause() {
        super.onPause();
        if (actionBar != null) {
            actionBar.closePopWindow();
        }
        _onPauseActivity();
        onPauseActivity();
    }

    protected void _onPauseActivity() {
    }

    protected void onPauseActivity() {
    }

    @Override
    final protected void onStop() {
        super.onStop();
        _onStopActivity();
        onStopActivity();
    }

    protected void _onStopActivity() {
    }

    protected void onStopActivity() {
    }

    @Override
    final protected void onStart() {
        super.onStart();
        _onStartActivity();
        onStartActivity();
    }

    protected void _onStartActivity() {
    }

    protected void onStartActivity() {
    }

    @Override
    final protected void onRestart() {
        super.onRestart();
        _onRestartActivity();
        onRestartActivity();
    }

    protected void _onRestartActivity() {
    }

    protected void onRestartActivity() {
    }

    @Override
    final protected void onDestroy() {
        dismissLoading();
        _onDestroyActivity();
        onDestroyActivity();
        super.onDestroy();
    }

    protected void _onDestroyActivity() {
    }

    protected void onDestroyActivity() {
    }
}
